
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

#include <sock.h>
#include <conf.h>

#include "setting.h"

void usage()
{
	printf("Usage:\n");
	printf("\t-d : daemon\n");
	printf("\t-p : x port\n");
	printf("\t-e : x program\n");
	printf("\t-a : x args\n");
	printf("\t-f : x config file\n");
	
	return;
}

void setopt(int argc, char *argv[])
{
	int opt;	
	while((opt = getopt(argc, argv, "dp:e:a:f:")) != -1) {
		switch(opt) {
			case 'd':
				g_setting.daemon = 1;
				break;
			case 'p':
				g_setting.port = atoi(optarg);
				break;
			case 'e':
				strncpy(g_setting.exec, optarg, sizeof(g_setting.exec)-1);
				break;
			case 'a':
				strncpy(g_setting.args, optarg, sizeof(g_setting.args)-1);
				break;
			case 'f':
				strncpy(g_setting.conf, optarg, sizeof(g_setting.conf)-1);
				break;
			default:
				usage();
				exit(1);
				break;
		}
	}

	return;
}

void sig_child(int no)
{
	while(waitpid(-1, 0, WNOHANG) >= 0);		
	
	return;
}


int main(int argc, char *argv[]) 
{
	int listenfd, fd;

	setting_load("lmail_master.conf");

	setopt(argc, argv);

	if(strlen(g_setting.conf) > 0) {
		setting_load(g_setting.conf);
	}

	if(strlen(g_setting.exec) == 0 || g_setting.port == 0) {
		printf("config error\n");
		exit(1);
	}

	if(g_setting.daemon) {
		printf("daemon mode\n");
		if(daemon(1, 0) == -1) {
			exit(1);
		}
	}

	signal(SIGPIPE, SIG_IGN);
	signal(SIGCHLD, sig_child);

	listenfd = sock_listen(NULL, g_setting.port);
	if(listenfd == -1) {
		exit(1);
	}

	while(1) { 
		fd = sock_accept(listenfd);
		if(fd == -1) {
			continue;
		}

		switch(fork()) {
			case 0:
				close(STDIN_FILENO);
				close(STDOUT_FILENO);
				close(STDERR_FILENO);
				dup2(fd, STDIN_FILENO);
				dup2(fd, STDOUT_FILENO);
				dup2(fd, STDERR_FILENO);
				close(listenfd);
				close(fd);
				execl(g_setting.exec, g_setting.args);
				exit(1);
				break;
			case -1:
				close(listenfd);
				close(fd);
				exit(1);
				break;
			default:
				close(fd);
				break;
		}

	}

	return 0;
}

